home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Game-Power
/
Amiga Game-Power.iso
/
pd mix ii
/
access
/
hddriver
/
support
/
fixdisk.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-05-20
|
6KB
|
196 lines
#include <stdio.h>
#include <exec/types.h>
#include <exec/memory.h>
#include "harddisk.h"
#include <ctype.h>
struct MsgPort * diskport;
struct IOExtHD * diskreq;
BYTE sector[ HD_SECTOR ];
struct hd_FirstSector first;
extern struct MsgPort * CreatePort ();
extern struct IORequest * CreateExtIO ();
extern LONG OpenDevice ();
extern LONG DoIO ();
main()
{
long error;
diskport = CreatePort ( 0L , 0L );
if ( diskport == NULL ) {
printf ( "Error in CreatePort ()\n" );
}
else {
diskreq = (struct IOExtHD *)
CreateExtIO ( diskport , (LONG) sizeof ( struct IOExtHD ) );
if ( diskreq == NULL ) {
printf ( "CreateExtIO() failed\n" );
}
else {
error = OpenDevice ( HD_NAME , 0L , diskreq , 0L );
if ( error != 0 ) {
printf ( "Error value returned by OpenDevice was %ld\n" , error );
}
else {
diskreq->iohd_TD.iotd_Req.io_Command = CMD_READ;
diskreq->iohd_TD.iotd_Req.io_Data = (APTR) &first;
diskreq->iohd_TD.iotd_Req.io_Length = sizeof ( first );
diskreq->iohd_TD.iotd_Req.io_Offset = 0;
if ( DoIO ( diskreq ) != 0 ) {
printf ( "Error in reading first sector information\n" );
}
else {
if ( first.magic != HD_MAGIC )
printf ( "Header sector information not found (wrong magic number)\n" );
else
do_commands ();
}
CloseDevice ( diskreq );
}
DeleteExtIO ( diskreq , (LONG) sizeof ( struct IOExtHD ) );
}
DeletePort ( diskport );
}
}
do_commands ()
{
long block;
int i;
char buf[ 80 ];
int retry_limit;
while ( 1 ) {
printf ( "\nDisk Information:\n\n" );
printf ( "%4ld cylinders\n" , first.cylinders );
printf ( "%4ld park cylinder\n" , first.park_cylinder );
printf ( "%4ld heads\n" , first.heads );
printf ( "%4ld sectors\n" , first.sectors );
printf ( "%4ld map sectors\n" , first.map_sectors );
printf ( "%4ld bad sectors\n" , first.bad_sectors );
printf ( "%4ld write precompensation\n" , first.precomp );
printf ( "\nBad blocks: " );
for ( i = 0; i < first.bad_sectors; i++ )
printf ( "%ld " , (long)first.map[i] );
printf ( "\n\n" );
diskreq->iohd_TD.iotd_Req.io_Command = CMD_FLUSH;
DoIO ( diskreq );
diskreq->iohd_TD.iotd_Req.io_Command = CMD_CLEAR;
DoIO ( diskreq );
printf ( "Enter block number or (q)uit: " );
if ( gets ( buf ) == NULL )
return;
if ( buf[0] == 'q' || buf[0] == 'Q' )
return;
if ( sscanf ( buf , "%ld" , &block ) != 1 ) {
printf ( "Illegal block number\n" );
}
else {
printf ( "Reading block %ld\n" , block );
diskreq->iohd_TD.iotd_Req.io_Command = CMD_READ;
diskreq->iohd_TD.iotd_Req.io_Data = (APTR) §or[0];
diskreq->iohd_TD.iotd_Req.io_Length = HD_SECTOR;
diskreq->iohd_TD.iotd_Req.io_Offset = block * HD_SECTOR;
if ( DoIO ( diskreq ) != 0 ) {
while ( 1 ) {
printf ( "Failed to read sector - enter retry count: " );
if ( gets ( buf ) == NULL )
return;
if ( sscanf ( buf , "%d" , &retry_limit ) != 1 )
retry_limit = 1;
if ( retry_limit <= 0 )
break;
for ( i = 0; i < retry_limit; i++ ) {
printf ( "Reading block %ld\n" , block );
diskreq->iohd_TD.iotd_Req.io_Command = CMD_READ;
diskreq->iohd_TD.iotd_Req.io_Data = (APTR) §or[0];
diskreq->iohd_TD.iotd_Req.io_Length = HD_SECTOR;
diskreq->iohd_TD.iotd_Req.io_Offset = block * HD_SECTOR;
if ( DoIO ( diskreq ) == 0 )
break;
}
if ( i >= retry_limit ) {
printf ( "Failed to read sector after %d attempts - setting buffer to 0's\n" ,
retry_limit );
for ( i = 0; i < HD_SECTOR; i++ )
sector[i] = 0;
}
else {
printf ( "Sector successfully read after %d retries\n" , i );
break;
}
}
}
printf ( "(u)nlink the sector or\n(w)rite the sector? " );
if ( gets ( buf ) == NULL )
return;
if ( buf[0] == 'u' || buf[0] == 'U' ) {
while ( first.bad_sectors < HD_MAP_SIZE
&& first.map[ first.bad_sectors ] == MAP_MARK_BAD )
first.bad_sectors++;
if ( first.bad_sectors >= HD_MAP_SIZE ) {
printf ( "Bad sector map table is full!\n" );
}
else {
/* write out sector at block first.bad_sectors */
printf ( "Writing sector buffer to block %ld\n" ,
first.bad_sectors + HD_MAP_SECTORS );
diskreq->iohd_TD.iotd_Req.io_Command = CMD_WRITE;
diskreq->iohd_TD.iotd_Req.io_Data = (APTR) §or[0];
diskreq->iohd_TD.iotd_Req.io_Length = HD_SECTOR;
diskreq->iohd_TD.iotd_Req.io_Offset =
( first.bad_sectors + HD_MAP_SECTORS ) * HD_SECTOR;
if ( DoIO ( diskreq ) != 0 ) {
printf ( "Failed to write block - bad sector not removed\n" );
}
else {
/* change map */
first.map[ first.bad_sectors++ ] = block;
/* write out sector map */
diskreq->iohd_TD.iotd_Req.io_Command = CMD_WRITE;
diskreq->iohd_TD.iotd_Req.io_Data = (APTR) &first;
diskreq->iohd_TD.iotd_Req.io_Length = sizeof ( first );
diskreq->iohd_TD.iotd_Req.io_Offset = 0;
if ( DoIO ( diskreq ) != 0 ) {
printf ( "Failed to write first sectors\n" );
return;
}
printf ( "\nUnlinked - WARNING: you must reboot for driver to learn of relinking\n\n" );
}
}
}
else if ( buf[0] == 'w' || buf[0] == 'W' ) {
printf ( "Writing block %ld\n" , block );
diskreq->iohd_TD.iotd_Req.io_Command = CMD_WRITE;
diskreq->iohd_TD.iotd_Req.io_Data = (APTR) §or;
diskreq->iohd_TD.iotd_Req.io_Length = HD_SECTOR;
diskreq->iohd_TD.iotd_Req.io_Offset = block * HD_SECTOR;
if ( DoIO ( diskreq ) != 0 ) {
printf ( "Failed to rewrite sector\n" );
}
else
printf ( "Rewrite successful\n" );
}
else {
printf ( "Sector not unlinked or rewritten\n" );
}
}
}
}